package com.erp.security.filter;

import java.io.IOException;
import java.util.List;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.commons.lang3.StringUtils;
import org.springframework.security.authentication.AuthenticationServiceException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.RememberMeServices;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

import com.danga.MemCached.MemCachedClient;
import com.erp.Resource.Resouce;
import com.erp.Resource.SomeStatic;
import com.erp.dao.UserDAO;
import com.erp.entity.Roles;
import com.erp.entity.Users;
import com.erp.exception.MyException;
import com.erp.form.ErpObject;

/*
 * MyUsernamePasswordAuthenticationFilter
 attemptAuthentication
 this.getAuthenticationManager()
 ProviderManager.java
 authenticate(UsernamePasswordAuthenticationToken authRequest)
 AbstractUserDetailsAuthenticationProvider.java
 authenticate(Authentication authentication)
 P155 user = retrieveUser(username, (UsernamePasswordAuthenticationToken) authentication);
 DaoAuthenticationProvider.java
 P86 loadUserByUsername
 */
@SuppressWarnings("unused")
public class MyUsernamePasswordAuthenticationFilter extends
		UsernamePasswordAuthenticationFilter implements SomeStatic {
	private MemCachedClient memcachedClient;
	
	public MemCachedClient getMemcachedClient() {
		return memcachedClient;
	}

	public void setMemcachedClient(MemCachedClient memcachedClient) {
		this.memcachedClient = memcachedClient;
	}


	private UserDAO userMapper;

	@Override
	public RememberMeServices getRememberMeServices() {
		return super.getRememberMeServices();
	}

	@Override
	public void setRememberMeServices(RememberMeServices rememberMeServices) {
		super.setRememberMeServices(rememberMeServices);
	}

	public UserDAO getUserMapper() {
		return userMapper;
	}

	public void setUserMapper(UserDAO userMapper) {
		this.userMapper = userMapper;
	}

	@Override
	public void afterPropertiesSet() {
		// TODO Auto-generated method stub
		super.afterPropertiesSet();
	}

	
	@Override
	public Authentication attemptAuthentication(HttpServletRequest request,
			HttpServletResponse response)  throws MyException {
		if (!request.getMethod().equals("POST")) {
			throw new MyException("传输方式不正确");//测试
		}
		
		String rand = "";

		HttpSession session = request.getSession();
		String username = "";
		username = obtainUsername(request);
		String password = obtainPassword(request);

		//		if (session.getAttribute("rand") != null) {
		//			rand = session.getAttribute("rand").toString();
		//		} else {
		//			throw new AuthenticationServiceException("验证码超时");
		//
		//		}
	

		String temp = "";
		if (username.equals("") || password.equals("")) {

			throw new AuthenticationServiceException("用户名或密码不能为空");
		}
		// 验证用户账号与密码是否对应
		username = username.trim();
		Users users = null;
		List<ErpObject> list = this.userMapper.findByName(username);
		if (list.size() != 0) {
			users = (Users)list.get(0);
		}
		if (users == null) {

			throw new AuthenticationServiceException("用户不存在");
		} else {

			temp = password;
			password =Resouce.passwordFlite(password, username);
		}

		// if(!users.getPassword().equals(password)) {
		if (!users.getPassWord().equals(password)) {
			/*
			 * 
			 * if (forwardToDestination) {
			 * request.setAttribute(WebAttributes.AUTHENTICATION_EXCEPTION,
			 * exception); } else { HttpSession session =
			 * request.getSession(false);
			 * 
			 * if (session != null || allowSessionCreation) {
			 * request.getSession(
			 * ).setAttribute(WebAttributes.AUTHENTICATION_EXCEPTION,
			 * exception); } }
			 */
			throw new AuthenticationServiceException("用户名或密码不正确");
		}
		if(request.getParameter(USER_TYPE) == null){
			throw new AuthenticationServiceException("类型不能为空");
		}
		boolean flag = false;// 登录的角色 进行循环匹配
		for (Roles role : users.getRolesList()) {
			if(String.valueOf(role.getId()).equals((request.getParameter(USER_TYPE).toString().trim()))){
				users.setCurrent(role.getName());
				flag = true;
				break;
			}
		}
		if(!flag){
			throw new AuthenticationServiceException("类型选择不正确");
		}
		// UsernamePasswordAuthenticationToken实现 Authentication
		UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(
				users.getUserName(), temp);
		// Place the last username attempted into HttpSession for views
		request.setAttribute("_spring_security_remember_me", true);
		// 允许子类设置详细属性
		
		setDetails(request, authRequest);
		// 运行UserDetailsService的loadUserByUsername 再次封装Authentication
		return this.getAuthenticationManager().authenticate(authRequest);
	}

	@Override
	public void doFilter(ServletRequest req, ServletResponse res,
			FilterChain chain) throws IOException, ServletException {
		// TODO Auto-generated method stub
		super.doFilter(req, res, chain);
	}

	protected void checkValidateCode(HttpServletRequest request) {
		HttpSession session = request.getSession();

		String sessionValidateCode = obtainSessionValidateCode(session);
		// 让上一次的验证码失效
		session.setAttribute(VALIDATE_CODE, null);
		String validateCodeParameter = obtainValidateCodeParameter(request);
		if (StringUtils.isEmpty(validateCodeParameter)
				|| !sessionValidateCode.equalsIgnoreCase(validateCodeParameter)) {
			throw new AuthenticationServiceException("validateCode.notEquals");
		}
	}

	private String obtainValidateCodeParameter(HttpServletRequest request) {
		Object obj = request.getParameter(VALIDATE_CODE);
		return null == obj ? "" : obj.toString();
	}

	protected String obtainSessionValidateCode(HttpSession session) {
		Object obj = session.getAttribute(VALIDATE_CODE);
		return null == obj ? "" : obj.toString();
	}

	@Override
	protected String obtainUsername(HttpServletRequest request) {
		Object obj = request.getParameter(USERNAME);
		return null == obj ? "" : obj.toString();
	}

	@Override
	protected String obtainPassword(HttpServletRequest request) {
		Object obj = request.getParameter(PASSWORD);
		return null == obj ? "" : obj.toString();
	}

}
